package com.ada.secure;

import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.engines.RSAEngine;
import org.bouncycastle.crypto.generators.RSAKeyPairGenerator;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.Security;
import java.security.SecureRandom;
import java.math.BigInteger;

public class BouncyCastleRSAExample {
    public static void main(String[] args) throws Exception {
        Security.addProvider(new BouncyCastleProvider());

        // Generate RSA key pair
        AsymmetricCipherKeyPair keyPair = generateRSAKeyPair();

        // Encrypt and decrypt using RSA
        String originalText = "Hello, Bouncy Castle!";
        byte[] encryptedData = encryptRSA(originalText.getBytes(), keyPair);
        byte[] decryptedData = decryptRSA(encryptedData, keyPair);

        System.out.println("Original Text: " + originalText);
        System.out.println("Encrypted Data: " + new String(encryptedData));
        System.out.println("Decrypted Text: " + new String(decryptedData));
    }

    // Generate RSA key pair
    public static AsymmetricCipherKeyPair generateRSAKeyPair() {
        RSAKeyPairGenerator keyPairGenerator = new RSAKeyPairGenerator();
        RSAKeyGenerationParameters keyGenParams = new RSAKeyGenerationParameters(
                BigInteger.valueOf(65537), // Public exponent
                new SecureRandom(),        // SecureRandom for key generation
                2048,                      // RSA key size in bits
                80                         // Miller-Rabin certainty (80 provides a high level of confidence)
        );
        keyPairGenerator.init(keyGenParams);
        return keyPairGenerator.generateKeyPair();
    }

    // Encrypt using RSA public key
    public static byte[] encryptRSA(byte[] data, AsymmetricCipherKeyPair keyPair) {
        RSAEngine rsaEngine = new RSAEngine();
        rsaEngine.init(true, keyPair.getPublic());

        return rsaEngine.processBlock(data, 0, data.length);
    }

    // Decrypt using RSA private key
    public static byte[] decryptRSA(byte[] data, AsymmetricCipherKeyPair keyPair) {
        RSAEngine rsaEngine = new RSAEngine();
        rsaEngine.init(false, keyPair.getPrivate());

        return rsaEngine.processBlock(data, 0, data.length);
    }
}
